/*
 * TestSegv.cpp
 *
 *  Created on: Mar 5, 2012
 *      Author: user
 */

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <sys/wait.h>

#include "MemoryManager.h"

/*
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>

#define handle_error(msg) \
     do { perror(msg); exit(EXIT_FAILURE); } while (0)

char *buffer;
int pagesize;

static void
handler(int sig, siginfo_t *si, void *unused)
{
	printf("Got SIGSEGV at address: 0x%lx\n",
			(long) si->si_addr);

	if (mprotect(buffer + pagesize * 2, pagesize, PROT_READ | PROT_WRITE) == -1)
		handle_error("mprotect");

}
*/

int main(int argc, char *argv[])
{

/*
	char *p;
	struct sigaction sa;

	sa.sa_flags = SA_SIGINFO;
	sigemptyset(&sa.sa_mask);
	sa.sa_sigaction = handler;
	if (sigaction(SIGSEGV, &sa, NULL) == -1)
		handle_error("sigaction");

	pagesize = sysconf(_SC_PAGE_SIZE);
	if (pagesize == -1)
		handle_error("sysconf");

	// Allocate a buffer aligned on a page boundary; initial protection is PROT_READ | PROT_WRITE

	buffer = (char*)memalign(pagesize, 4 * pagesize);
	if (buffer == NULL)
		handle_error("memalign");

	printf("Start of region:        0x%lx\n", (long) buffer);

	if (mprotect(buffer + pagesize * 2, pagesize, PROT_NONE) == -1)
		handle_error("mprotect");

	for (p = buffer ; (long)p < (long)buffer + 4 * pagesize; )
		*(p++) = 'a';

	printf("Loop completed\n");
	*/


	sem_t sem;
	unsigned int value = 1;
	int status;

	sem_init(&sem, 1, value);

	extern	char	end[];

	// arianna iorio

	caddr_t addr = (caddr_t)((long)(end + 0x4FFFFFFFL) &~ 0x0FFFFFFFL);

	printf("VAddr start = %p\n", addr);

	installMemoryWatcher();

	void *test = malloc(16);

	free(test);

	test = malloc(16);

	*(char*)test = 0;

	removeMemoryWatcher();

	pid_t pID = fork();

	if( pID == 0 )
	{
		// Clone
		sleep(2);
		sem_wait(&sem);

		protectAll();

		printf("\nClone Reading from memory buffer\n");

		char b = *(char*)test;

		printf("\nClone Writing to memory buffer\n");

		*(char*)test = 1;

		unprotectAll();

		listDirtyPages();

		printf("\nChild exit = %d\n", *(char*)test );

		sem_post(&sem);
	}
	else
	{
		// Master
		sem_wait(&sem);

		printf("\nMaster Reading from memory buffer\n");

		char b = *(char*)test;

		printf("\nMaster Writing to memory buffer\n");

		*(char*)test = 2;

		printf("\nMaster exit1 = %d\n", *(char*)test );

		sem_post(&sem);

		wait(&status);

		printf("\nMaster exit2 = %d\n", *(char*)test );

	}

	free( test );

	exit(EXIT_SUCCESS);
}
